﻿//This filter is tested and seems to work correctly

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// This will a also return a base color of every given color
    /// </summary>
    public class BaseColorSegmentation2 : BaseColorSegmentation
    {
        protected Dictionary<string, Color> aColorAssignment = new Dictionary<string, Color>();
        protected bool m_bOnlyPureColors = false;

        protected Dictionary<string, string> aComplementChannel = new Dictionary<string, string>();

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseColorSegmentation2"/> class.
        /// </summary>
        public BaseColorSegmentation2()
        {
            aColorAssignment.Add("R", Color.Red);
            aColorAssignment.Add("G", Color.Green);
            aColorAssignment.Add("B", Color.Blue);
            aColorAssignment.Add("RG", Color.Yellow);
            aColorAssignment.Add("RB", Color.Magenta);
            aColorAssignment.Add("BG", Color.Cyan);
            aColorAssignment.Add("RBG", Color.Gray);

            //This is the complement, each channel + complement has to result in complete word "rgb"
            aComplementChannel.Add("R", "GB");
            aComplementChannel.Add("G", "RB");
            aComplementChannel.Add("B", "RG");
            aComplementChannel.Add("RG", "B");
            aComplementChannel.Add("RB", "G");
            aComplementChannel.Add("BG", "R");
            aComplementChannel.Add("RBG", "");
        }

        /// <summary>
        /// Use this to create only pure colors
        /// </summary>
        /// <param name="_bOnlyPureColors"></param>
        public BaseColorSegmentation2(bool _bOnlyPureColors)
        {
            m_bOnlyPureColors = _bOnlyPureColors;
        }

        /// <summary>
        /// Execute this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;
            int nHeight = bitmap.Height;
            int nWidth = bitmap.Width;

            Color colorAssignment = Color.Transparent;
            Color color = Color.Transparent;

            string sTemp = string.Empty;
            //string sRGB = "RGB";
            for (int y = 0; y < nHeight; y++)
            {
                for (int x = 0; x < nWidth; x++)
                {
                    color = bitmap.GetPixel(x, y);
                    sTemp = ColorFunctions.RGBMaxLetters(color);
                    colorAssignment = aColorAssignment[sTemp];
                    
                    //only if the color is a pure base color like full red the color is set
                    //otherwise it's left black

                    if (m_bOnlyPureColors)
                    {
                        string sComplement = String.Empty;
                        int nCount = 0;
                        PureColor(sTemp, out sComplement, out nCount);
                        bitmap.SetPixel(x, y, nCount == sComplement.Length ? colorAssignment : Definitions.Black);
                    }
                    else
                    {
                        bitmap.SetPixel(x, y, colorAssignment);
                    }
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// return a pure color
        /// </summary>
        /// <param name="sTemp"></param>
        /// <param name="sComplement"></param>
        /// <param name="nCount"></param>
        private void PureColor(string sTemp, out string sComplement, out int nCount)
        {
            sComplement = aComplementChannel[sTemp];
            nCount = 0;
            foreach (char ch in sComplement)
            {
                nCount += ColorFunctions.GetChannel(ch) == 0 ? 1 : 0;
            }
        }
    }
}
